#include <stdio.h>

using namespace std;
#define MAX_VEX 500
#define MAX_LENGTH 999999

typedef struct Graph{
    int vTeamNum[MAX_VEX];
    int arc[MAX_VEX][MAX_VEX];
    int vNum, aNum;
}Graph;

Graph g;
int shortestLength;
int shortestPathNum;
int maxTeamNum;
bool isInPath[MAX_VEX];

void findPath(int v, const int dest, int length, int teamNum){
    if(length > shortestLength)     //Pruning
        return;

    int i;
    if(v == dest){
        if(shortestLength > length){
            shortestLength = length;
            maxTeamNum = teamNum;
            shortestPathNum = 1;
        }
        else if(shortestLength == length){
            shortestPathNum++;
            if(maxTeamNum < teamNum){
                maxTeamNum = teamNum;
            }
        }
    }
    else{
        for(i=0; i<g.vNum; i++){
            if(g.arc[v][i]<MAX_LENGTH && !isInPath[i]){
                isInPath[v] = true;
                findPath(i, dest, length+g.arc[v][i], teamNum+g.vTeamNum[i]);
                isInPath[v] = false;
            }
        }
    }
}
int main(){
    freopen("data.txt", "r", stdin);

    int src, dest;
    while(EOF!=scanf("%d%d%d%d", &g.vNum, &g.aNum, &src, &dest)){
        int i, j;
        //input & init
        shortestLength = MAX_LENGTH;
        shortestPathNum = 0;
        maxTeamNum = -1;
        for(i=0; i<g.vNum; i++){
            scanf("%d", &g.vTeamNum[i]);
            for(j=0; j<g.vNum; j++){
                g.arc[i][j] = MAX_LENGTH;
            }
            isInPath[i] = false;
        }
        for(i=0; i<g.aNum; i++){
            int a, b, l;
            scanf("%d%d%d", &a, &b, &l);
            g.arc[a][b] = l;
            g.arc[b][a] = l;
        }

        findPath(src, dest, 0, g.vTeamNum[src]);

        printf("%d %d\n", shortestPathNum, maxTeamNum);
    }//while

    return 0;
}
